<?php
namespace App\Service;

use Hyperf\DbConnection\Db;
use App\Service\PlayletService;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use GuzzleHttp\Client;

class DyCouponService extends CommicService
{

    //获取token
    public static $getTokenUrl = "https://open.douyin.com/oauth/client_token/";
    static  $consumeUrl = 'https://open.douyin.com/api/promotion/v1/coupon/batch_consume_coupon';

    public function __construct()
    {
        $container = ApplicationContext::getContainer();
        $this->redisService = $container->get(\Hyperf\Redis\Redis::class);
    }
    /**
     * 插入用户券信息
     * author bobo
     * date 2024-04-01
     */
    public function insertCoupon($params){
        //加redis锁
        $handleKey = 'dy_data_user_coupon_live';
        $returnData = ['error_no' => 400,'err_msg' => "key loct",'notify_status' => 'fail'];
        try {
            $keyData = $this->redisService->get($handleKey);
            if(!empty($keyData)){
                return $returnData;
            }else{
                $this->redisService->set($handleKey,1);
            }
            //查看
            $msg = $params['msg'];
            $jsonData = json_decode($msg,true);
            if(!empty($jsonData)){
                $coupon_id = $jsonData['coupon_id'];
                //判断redis中是否这个，如果有这个幂等键，则直接返回成功
                $redis_key = 'dy_coupon_list';
                $redisData = $this->redisService->sIsMember($redis_key,$coupon_id);

                if(!empty($redisData)){
                    $returnData = ['error_no' => 0,'err_msg' => "",'notify_status' => 'success'];
                    $this->redisService->del($handleKey);
                    return $returnData;
                //插入用户领取表中
                }else{
                    $app_id = $jsonData['app_id'];
                    $xc_open_id =$jsonData['open_id'];
                    //先查询对应的小程序
                    $appletInfo = Db::table('applet')->select('id')->where('app_id',$app_id)->first();
                    if(!empty($appletInfo)){
                        $userInfo = Db::table('data_user_'.$appletInfo->id)
                            ->select('id')
                            ->where('xc_open_id',$xc_open_id)
                            ->first();
                        //再查询对应的用户信息
                        if(!empty($userInfo)){

                            $insertData  =[
                                'app_id' => $app_id,
                                'applet_id' => $appletInfo->id,
                                'user_id' => $userInfo->id,
                                'xc_open_id' => $xc_open_id,
                                'coupon_id' => $jsonData['coupon_id'], //券id，由平台生成，全局唯一
                                'coupon_status' => $jsonData['coupon_status'], //券状态，10：已领取
                                'receive_time' => date('Y-m-d H:i:s',$jsonData['receive_time']), //领券时间，单位秒
                                'applet_coupon_id' => $jsonData['merchant_meta_no'], //内部券的ID
                                'valid_begin_time' =>  date('Y-m-d H:i:s',$jsonData['valid_begin_time']), //券有效期开始时间，单位秒
                                'valid_end_time' =>  date('Y-m-d H:i:s',$jsonData['valid_end_time']), //券有效期结束时间，单位秒
                                'talent_open_id' => !empty($jsonData['talent_open_id']) ?? '', //发券人的小程序open id
                                'talent_account' => !empty($jsonData['talent_account']) ?? '', //发券人的抖音号
                                'union_id' => $jsonData['union_id'], //发券人的抖音号
                                'created_at' => date('Y-m-d H:i:s',time())
                            ];
                            $is_insert = Db::table('data_user_coupon')->insert($insertData);
                            if($is_insert){
                                $this->redisService->sAdd($redis_key,$coupon_id);
                                $this->redisService->del($handleKey);
                                $returnData = ['error_no' => 0,'err_msg' => "",'notify_status' => 'success'];
                                return $returnData;
                            }
                        }
                    }
                }
            }
            $this->redisService->del($handleKey);
            $returnData['err_msg'] = 'data Error';
        }catch (\Exception $e){
            $this->redisService->del($handleKey);
            var_dump($e->getMessage());
            $returnData['err_msg'] = 'catch Error';
        }
        return $returnData;
    }

    /**
     * 获取用户券信息
     * author bobo
     * date 2024-04-01
     */
    public function getUserCoupon($coupon_id,$applet_id,$user_id){
        $nowTime = date('Y-m-d H:i:s',time());

        $couponInfo = Db::table('data_user_coupon')
            ->select(['data_user_coupon.id','data_user_coupon.app_id','applet.app_secret','data_user_coupon.applet_id',
                'data_user_coupon.coupon_id','data_user_coupon.applet_coupon_id','applet_coupon.free_episodes'])
            ->where('data_user_coupon.coupon_id', $coupon_id)
            ->where('data_user_coupon.applet_id', $applet_id)
            ->where('data_user_coupon.user_id', $user_id)
            ->where('data_user_coupon.is_use', 'N')
            ->where('data_user_coupon.valid_begin_time','<=',$nowTime)
            ->where('data_user_coupon.valid_end_time','>=',$nowTime)
            ->leftJoin('applet_coupon','applet_coupon.id','=','data_user_coupon.applet_coupon_id')
            ->leftJoin('applet','applet.id','=','data_user_coupon.applet_id')
            ->first();

        return $couponInfo;
    }
    /**
     * 用户核销券
     * author bobo
     * date 2024-04-01
     */
    public function consumeCoupon($couponInfo,$open_id){
        $returnResult = array();
        try {
            $accessToken = $this->getDyAccessToken($couponInfo->applet_id,$couponInfo->app_id,$couponInfo->app_secret);
            $params         = [
                "open_id"   => (string)$open_id, //用户openid
                "consume_out_no"   => $couponInfo->applet_coupon_id,
                "app_id"   =>  $couponInfo->app_id,
                "coupon_id_list" => [$couponInfo->coupon_id],
                "consume_time" => time(),
            ];
            $url = self::$consumeUrl;
            $postResult  = $this->request($params, $url,'POST',$accessToken);
            if($postResult['err_no'] == 0){
                $returnResult =  $postResult['data']['results'][0];
            }else {
                $returnResult = $postResult;
            }
        }catch (\Exception $e){
            $returnResult['err_no'] = 0;
            $returnResult['err_msg'] = $e->getMessage().'|'.$e->getLine();
        }
        return $returnResult;
    }

    /**
     * 解锁集数
     * author bobo
     * date 2024-04-01
     */
    public function unlockEpisodes($couponInfo,$playlet_id,$playlet_number,$user_id,$applet_id) {

        $data = [];
        $inser_data = [];
        $inser_data['user_id'] = $user_id;
        $inser_data['applet_id'] = $applet_id;
        $inser_data['playlet_id'] = $playlet_id;
        $inser_data['create_at'] = date('Y-m-d H:i:s');
        $inser_data['order_id'] = $couponInfo->id;
        $inser_data['amount'] = 0;
        $inser_data['tpye'] = 3;
        $free_episodes = (integer)$couponInfo->free_episodes-1;
        if($free_episodes == 0){
            $playlet_number = [$playlet_number];
        }else{
            $playlet_number = range($playlet_number, $playlet_number+$free_episodes);
        }
        #一集还是两集
        if(is_array($playlet_number)){
            $redis_key = "log:playlet:pay:".$applet_id.":".$playlet_id;
            $playlet_log_list = $this->redisService->hGet($redis_key,(string)$user_id);
            $playlet_log_list = json_decode($playlet_log_list,true);

            foreach ($playlet_number as $key => $value) {
                if(!empty($playlet_log_list)) {

                    if(in_array($value,$playlet_log_list)) {
                        continue;
                    }
                }
                $inser_data['playlet_number'] = $value;
                $data[] = $inser_data;

            }
        }
        if($data) {
            Db::table('data_user_pay_playlet_log')->insert($data);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method,string $access_token = null)
    {
        $client   = new Client([
            'timeout' => 30
        ]);
        $headers       = ['Content-Type' => 'application/json'];
        if(!empty($access_token)){
            $headers['access-token'] = $access_token;
        }

        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;//json_encode($params,JSON_UNESCAPED_UNICODE);
        }
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }

    public function getDyAccessToken($applet_id,$app_id,$app_secret){

        $key = 'dy_admin_access_token';
        $key .= $applet_id;
        $accessToken = $this->redisService->get($key);
        if(empty($accessToken)){
            $params         = [
                'grant_type' => 'client_credential',
                'client_key'    => $app_id,
                'client_secret'   => $app_secret
            ];
            //获取token
            $accessTokenInfo     = $this->request($params, self::$getTokenUrl,'POST');
            if (!empty($accessTokenInfo['data']['access_token'])){
                $accessToken = $accessTokenInfo['data']['access_token'];
                $this->redisService->setex($key,7100,$accessToken);
            }else{
                $accessToken = "";
            }
        }
        return $accessToken;
    }
}